#include "DateTime.h"
#include <sstream>
#include <iomanip>


void localtime_ex(struct tm*  const _Tm, time_t const* const _Time)
{
#ifdef WIN32
	localtime_s(_Tm, _Time);
#else
	localtime_r(_Time, _Tm);
#endif
}

CDateTime::CDateTime()
{
    m_now = cho::system_clock::now();
    time_t t = cho::system_clock::to_time_t(m_now);
    localtime_ex(&m_stTime, &t);
}
CDateTime::CDateTime(time_t t)
{
    m_now = cho::system_clock::from_time_t(t);
    localtime_ex(&m_stTime, &t);
}

CDateTime::CDateTime(const std::string& strTime, const std::string& strFmt )
{
    std::istringstream ss(strTime);
    ss >> std::get_time(&m_stTime, strFmt.c_str());
    m_now = cho::system_clock::from_time_t(std::mktime(&m_stTime));
}

CDateTime::CDateTime( cho::system_clock::time_point point)
{
    m_now = point;
    time_t t = cho::system_clock::to_time_t(m_now);
    localtime_ex(&m_stTime, &t);
}

std::string CDateTime::ToString(const std::string& strFmt )
{
    std::stringstream ss;
    auto time = std::put_time(&m_stTime, strFmt.c_str());
    ss << time;
    return ss.str();
}
time_t CDateTime::ToMSecs()
{
    return cho::system_clock::to_time_t(m_now);
}

//是否闰年
bool CDateTime::IsLeapYear(int nYear)
{
	return (0 != nYear % 100 && 0 == nYear % 4) || (0 == nYear % 400);
}

//获取当月天数
int CDateTime::GetMonthDays()
{
	int nMonth = Month();
	int nYear = Year();
	
	if (1 == nMonth || 3 == nMonth || 5 == nMonth || 7 == nMonth
		|| 8 == nMonth || 10 == nMonth || 12 == nMonth)
	{
		return 31;
	}
	else if (2 == nMonth)
	{
		if (IsLeapYear(nYear))
			return 29;
		else
			return 28;
	}
	else
	{
		return 30;
	}
}


CDateTime CDateTime::AddDays(int nDay)
{
    days_type d(nDay);
    auto dt = m_now + d;
    return dt;
}

CDateTime CDateTime::AddMonths(int nMon)
{
    int nMonth = nMon % 12;
    int nYear = nMon / 12;
    nMonth += m_stTime.tm_mon;

    struct tm currTime = m_stTime;
    currTime.tm_year = m_stTime.tm_year + nYear + nMonth / 12;

    currTime.tm_mon = nMonth % 12;

    
    return CDateTime(std::mktime(&currTime));

}

CDateTime CDateTime::AddYears(int nYear)
{
    struct tm currTime = m_stTime;
    currTime.tm_year += nYear;
    return CDateTime(std::mktime(&currTime));
}